import os
from functools import partial

from settings import settings
import gui

from graphics import graphics, request_replace

import pygame
from collision import Rect

import campaign

class CampaignsButton(gui.Button):
	graphic = "menu/campaigns.png"
	name = "campaigns"

class OptionsButton(gui.Button):
	graphic = "menu/options.png"
	name = "options"

class QuitButton(gui.Button):
	graphic = "menu/quit.png"
	name = "quit"
	
	def action(self):
		pygame.event.post(pygame.event.Event(pygame.QUIT))

class BackButton(gui.Button):
	graphic = "menu/back.png"
	name = "default"

request_replace(CampaignsButton, OptionsButton, QuitButton, BackButton)

class Menu(object):
	_DEFENCE = settings.fonts.title.render("Defence", True, (255, 255, 255), 
		(0, 0, 0))
	graphic = "menu/background.png"
	campaign = campaign.Campaign(os.path.join(settings.paths.campaigns, "menu"))
	
	def __init__(self):
		Filmstrip = partial(gui.Filmstrip, self)
		
		buttons = CampaignsButton(self), OptionsButton(self), QuitButton(self)
		main = Filmstrip(Rect(0, 64, 640, 192), *buttons)
		
		campaign_join = partial(os.path.join, settings.paths.campaigns)
		
		"""Map all campaign names to their folder path. A campaign is a
		directory with a campaign.txt file. The menu campaign in settings.txt is 
		excluded."""
		campaigns = dict((node, campaign_join(node)) 
			for node in os.listdir(settings.paths.campaigns)
			if os.path.isdir(campaign_join(node))
			and "campaign.txt" in os.listdir(campaign_join(node))
			and node != settings.menu.campaign)
		
		def button(_name, path):
			class Button(gui.Button):
				name = "campaign/%s" % _name
				graphic = os.path.join(path, "logo.png")
			
			request_replace(Button, relative=False)
			
			return Button(self)
		
		campaign_buttons = [button(_name, path) for _name, path in campaigns.iteritems()]
		campaign_buttons.append(BackButton(self))
		
		campaigns_strip = Filmstrip(Rect(0, 64, 640, 192), *campaign_buttons)
		
		options = Filmstrip(Rect(0, 64, 640, 192), BackButton(self))
		
		self.menus = {
			"default": main,
			"campaigns": campaigns_strip,
			"options": options,}
		
		for name, path in campaigns.iteritems():
			self.menus["campaign/%s" % name] = campaign.Campaign(path).show_map(self)
		
		self.widgets = [options, campaigns]
		self.current = [self.menus["default"]]
		
		self.rect = Rect((0, 0, 640, 480))

	def update(self):
		for widget in self.widgets:
			if widget in self.current:
				widget.update()
		
	def draw(self, surface):
		surface.fill((0, 0, 0), (0, 0, 640, 64))
		width, height = self._DEFENCE.get_size()
		surface.blit(self._DEFENCE, (320 - (width // 2), 0))
		
		menu_rect = Rect((0, 64, 640, 192))
		surface.blit(self.graphic, menu_rect)
		pygame.draw.line(surface, (0, 0, 0), menu_rect.bottomleft, menu_rect.bottomright, 1)
		
		for widget in self.current:
			widget.draw(surface)
		
		"""surface.fill((0, 0, 0))
		surface.fill((0, 0, 0), (0, 0, 640, 64))
		text = settings.title_font.render("Testing Campaign", True, (255, 255, 255), (0, 0, 0))
		width, height = text.get_size()
		surface.blit(text, (320 - (width // 2), -6))
		surface.blit(self.map, menu_rect)"""
		
	def event(self, event):
		if event.type == pygame.MOUSEBUTTONDOWN:
			if self.rect.collidepoint(event.pos):
				for widget in self.current:
					widget.event(event)
		
	def menu(self, name):
		self.current = [self.menus[name]]

request_replace(Menu, alpha=False)
